home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_400
/
438_01
/
stelnet.c
< prev
next >
Wrap
Text File
|
1994-12-19
|
26KB
|
952 lines
/*
* stelnet - A telnet client for the serial port
* Version 1.00 (December 20th, 1994)
*
* Copyright 1994 Riku Saikkonen (riku.saikkonen@pcb.compart.fi)
*
* This program is free software; you can redistribute and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program (as the file COPYING); if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* The author, Riku Saikkonen, can be contacted via the following means:
* E-mail: riku.saikkonen@pcb.compart.fi (preferred) or
* risaikko@freenet.hut.fi
* Paper mail: Riku Saikkonen
* Alakartanontie 4 B 63
* SF-02360 ESPOO
* Finland
*/
/*
* Known bugs:
* ZModem ZR[Q]INIT to telnet without a reply activates ZModem 8-bit clean
* mode (ZDLE ZDLE exits it)
*
* Todo list:
* user-selectable terminal types
* don't beep on local screen in put_ser() (affects only warnings etc.)
* debug mode (show IACs)
* ECHO option (local echo)
* TELNET options 5 (STATUS), 32-38?
* non-SGA mode + send Go Ahead command
* telnet handshaking (how?)
* telnet/serial options in synchronisation with sob/tob
* (difficult, not very useful)
*/
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <dos.h>
#include <time.h>
#include <tcp.h>
#define BANNER "stelnet 1.00"
#define COPYRIGHT1 \
"Copyright 1994 Riku Saikkonen (riku.saikkonen@pcb.compart.fi)"
#define COPYRIGHT2 \
"stelnet is free software, distributed under the terms of the GNU " \
"General\r\n" \
"Public License version 2, and comes with ABSOLUTELY NO WARRANTY; for " \
"details,\r\n" \
"see the documentation distributed with the program.\r\n"
/* Default telnet, serial buffer sizes (override with makefile) */
#ifndef TIBLEN
#define TIBLEN 512
#endif
#ifndef SIBLEN
#define SIBLEN 512
#endif
#ifndef TOBLEN
#define TOBLEN 8192
#endif
#ifndef SOBLEN
#define SOBLEN 8192
#endif
#ifndef SOBLIMIT
#define SOBLIMIT 512
#endif
/* Default loopcheck value (override with makefile) */
#ifndef LOOPCHECK
#define LOOPCHECK 100
#endif
typedef unsigned char BYTE;
typedef unsigned int WORD;
#define SE 240
#define BRK 243
#define IP 244
#define AO 245
#define AYT 246
#define EC 247
#define EL 248
#define SB 250
#define WILL 251
#define WONT 252
#define DO 253
#define DONT 254
#define IAC 255
#define IS 0
#define SEND 1
#define TELOPT_BINARY 0
#define TELOPT_ECHO 1
#define TELOPT_SGA 3
#define TELOPT_TTYPE 24
#define addsob(c) { if (sobp>=SOBLEN) sobp=0; /* Wrap */ \
if (sobp==sobs && sobp!=0) \
{sobs++;soverrun++;} /* Buffer overrun; lose first character */ \
sob[sobp]=c;sobp++; }
#define addtob(c) { if (tobp>=TOBLEN) tobp=0; /* Wrap */ \
if (tobp==tobs && tobp!=0) \
{tobs++;toverrun++;} /* Buffer overrun; lose first character */ \
tob[tobp]=c;tobp++; }
#define putstr(s) {fputs(s,stdout);}
void syntax(void);
int init_tel(void);
void deinit_tel(void);
#define ok_tel() tcp_tick(socket)
#define read_tel(buf,sz) sock_fastread(socket,buf,sz)
#define write_tel(buf,sz) sock_fastwrite(socket,buf,sz)
int init_ser(void);
int read_ser(BYTE *buf, int sz);
int write_ser(BYTE *buf, int sz);
int ok_ser(void);
int put_ser(char *s);
void deinit_ser(void);
int comport;
union REGS reg;
struct SREGS sreg;
char hostname[128];
int port;
unsigned long hostnum;
tcp_Socket *socket;
tcp_Socket socketdata;
int opt_bin;
int copt_cd,copt_localscr,copt_idle,copt_sendinit,copt_8bit;
char copt_username[30];
int main(int argc, char *argv[])
{
static BYTE tib[TIBLEN],tob[TOBLEN];
static BYTE sib[SIBLEN],sob[SOBLEN];
BYTE sibc,tibc;
static FILE *fp;
int sobs,sobp,tobs,tobp,sibend,tibend;
int i,j;
unsigned u=0;
int sercmd,teliac,quit,timewarn,itimewarn;
time_t stime,etime,itime,curtime;
unsigned char sercmdkey;
long soverrun,toverrun;
int clean8bit,clean8bitz,zmframe;
int loopcount,loop2count,notidle;
static char s[256],exit8bits[11]="-\030\030stelnet";
putstr(BANNER "\n" COPYRIGHT1 "\n" COPYRIGHT2 "\n");
if (argc<4) syntax();
comport=atoi(argv[1]);
if (comport<1 || comport>8)
{
putstr("Invalid COM port!\n");
exit(10);
}
comport--;
itime=etime=0;
copt_cd=copt_sendinit=1;copt_localscr=copt_idle=copt_8bit=0;
itimewarn=timewarn=0;
strcpy(copt_username,"Unknown");
stime=time(NULL);
sercmdkey=255;
for (i=4;i<argc;i++)
{
switch (tolower(argv[i][0]))
{
case 'i':
copt_idle=1;
putstr("Idle timeout checking on.\n");
break;
case 't':
timewarn=atoi(&argv[i][1]);
etime=stime+timewarn*60;
timewarn=300;
putstr("Time limit set.\n");
break;
case '8': copt_8bit=1;putstr("8-bit clean mode.\n");break;
case 'e':
sercmdkey=atoi(&argv[i][1]);
sprintf(s,"Escape character set to ASCII %d.\n",sercmdkey);
putstr(s);
break;
case 'c': copt_cd=0;putstr("Carrier Detect checking off.\n");break;
case 'l': copt_localscr=1;putstr("Local screen on.\n");break;
case 'x':
copt_sendinit=0;putstr("Not sending initialisation codes.\n");
break;
case 'd': /* Door information file */
if ((fp=fopen(&argv[i][2],"rb"))==NULL)
{
putstr("Error opening door information file!\n");
exit(9);
}
switch (tolower(argv[i][1]))
{
case 'p': /* PCBOARD.SYS */
fseek(fp,84,SEEK_SET);
fread(copt_username,sizeof(unsigned char),25,fp);
copt_username[25]=0; /* Purge spaces from right !!! */
fread(&u,sizeof(unsigned int),1,fp);
if (u<1440) /* !!! */
{
etime=stime+u*60;
timewarn=300;
}
putstr("PCBOARD.SYS read.\n");
break;
default: syntax();
}
fclose(fp);
break;
default: syntax();
}
}
if (init_ser()<0)
{
putstr("Error initialising serial port!\n");
exit(3);
}
/* VT-100: ESC c (reset), ESC [1;1f (home), ESC [2J (clear screen) */
if (copt_sendinit) put_ser("\033c\033[1;1f\033[2J");
put_ser("\r\n" BANNER "\r\n" COPYRIGHT1 "\r\n" COPYRIGHT2 "\r\n");
sprintf(s,"Serial escape character is ASCII %d.\r\n",sercmdkey);
putstr(s);
if (copt_8bit)
put_ser("In 8-bit clean mode; exit with '<255><^X><^X>stelnet'.\r\n");
if (etime!=0)
{
sprintf(s,"Time left: %.1f min\r\n",(etime-time(NULL))/60.0);
put_ser(s);
}
strcpy(hostname,argv[2]);
port=atoi(argv[3]);
sprintf(s,"\r\nTrying to connect to %s port %d...\r\n",hostname,port);
put_ser(s);
i=init_tel();
if (i<0)
{
if (i==-1) put_ser("Connection refused.");
else put_ser("Name resolver not working!");
put_ser(" Exiting.\r\n");
deinit_ser();
if (i==-1) exit(2); else exit(4);
}
put_ser("Connected. Type <ASCII 255> ? for a list of commands.\r\n");
sobs=sobp=tobs=tobp=sercmd=teliac=quit=0;
soverrun=toverrun=0;
zmframe=clean8bitz=0;
clean8bit=copt_8bit;
sibc=tibc=0;
loopcount=loop2count=notidle=1;
itimewarn=6;
/* Telnet initialisation IACs */
if (copt_sendinit)
{
tob[0]=IAC;tob[1]=DO;tob[2]=TELOPT_BINARY;
tob[3]=IAC;tob[4]=WILL;tob[5]=TELOPT_BINARY;opt_bin=1;
tob[6]=IAC;tob[7]=DO;tob[8]=TELOPT_ECHO;
tob[9]=IAC;tob[10]=WILL;tob[11]=TELOPT_SGA;
tob[12]=IAC;tob[13]=DO;tob[14]=TELOPT_SGA;
tob[15]=IAC;tob[16]=WILL;tob[17]=TELO